﻿using System;
using System.Collections.Generic;
using RepositoryFramework.Services;
using RepositoryFramework;
using Portal.Logic.Validators;
using Portal.Model;
using Portal.Repository;

namespace Portal.Logic.Services
{
	/// <summary>
	/// Class <see cref="ContactInfoService"/> define contact info service
	/// </summary>
	public class ContactInfoService : ServiceBase<IUnitOfWorkProvider<IPortalUnitOfWork>, IPortalUnitOfWork, IContactInfo>, IContactInfoService
	{
		#region Fields

		private readonly IContactInfoRepository _readOnlyRepository;

		#endregion Fields

		#region .ctor

		/// <summary>
		/// Class <see cref="ContactInfoService"/> constructor
		/// </summary>
		/// <param name="unitOfWork"></param>
		public ContactInfoService(IPortalUnitOfWorkProvider provider, IContactInfoValidator validator)
			: base(provider, validator)
		{
			if (GetReadOnlyUnitOfWork().ContactInfoRepository == null)
			{
				throw new ArgumentNullException("ContactInfoRepository");
			}
			_readOnlyRepository = GetReadOnlyUnitOfWork().ContactInfoRepository;
		}

		#endregion .ctor

		#region Methods

		/// <summary>
		/// Gets user contact infos by its login
		/// </summary>
		/// <param name="login"></param>
		/// <returns>User</returns>
		public IEnumerable<IContactInfo> GetUserContactInfosBy(string login)
		{
			return _readOnlyRepository.GetAllBy(login);
		}

		/// <summary>
		/// Delete all user contact infos
		/// </summary>
		/// <param name="user">The user</param>
		/// <param name="repository">The repository</param>
		public void DeleteAllBy(IContactInfoRepository repository, IUser user)
		{
			if (repository == null)
			{
				throw new ArgumentNullException("repository");
			}
			repository.DeleteAllBy(user);
		}

		/// <summary>
		/// Add or update user
		/// </summary>
		/// <param name="user">The user</param>
		/// <param name="repository">The repository</param>
		/// <param name="contactInfo">The contact info</param>
		public IContactInfo AddOrUpdate(IContactInfoRepository repository, IUser user, IContactInfo contactInfo)
		{
			if (contactInfo == null)
			{
				return null;
			}

			if (repository == null)
			{
				throw new ArgumentNullException("repository");
			}

			if (user == null)
			{
				throw new ArgumentNullException("user");
			}

			Validate(contactInfo);
			return repository.AddOrUpdate(user, contactInfo);
		}

		/// <summary>
		/// Add or update user
		/// </summary>
		/// <param name="user">The user</param>
		/// <param name="contactInfo">The contact info</param>
		public IContactInfo AddOrUpdate(IUser user, IContactInfo contactInfo)
		{
			using (var unitOfWork = GetTransactionalUnitOfWork())
			{
				var result = AddOrUpdate(_readOnlyRepository, user, contactInfo);
				unitOfWork.Save();
				return result;
			}

		}

		#endregion Methods
	}
}